let nextDataTextureIndex = 0;

export class TextureSampler {
  constructor() {
    this.minFilter = null;
    this.magFilter = null;
    this.wrapS = null;
    this.wrapT = null;
  }
}

export class Texture {
  constructor() {
    this.sampler = new TextureSampler();
    this.mipmap = true;
  }

  get format() {
    return 6408;//WebGLRenderingContext.RGBA;
  }

  get width() {
    return 0;
  }

  get height() {
    return 0;
  }

  get textureKey() {
    return null;
  }
}

export class ImageTexture extends Texture {
  constructor(img) {
    super();

    this._img = img;
    this._imgBitmap = null;

    if (img.src && img.complete) {
      if (img.naturalWidth) {
        this._promise = this._finishImage();
      } else {
        this._promise = Promise.reject('Image provided had failed to load.');
      }
    } else {
      this._promise = new Promise((resolve, reject) => {
        img.addEventListener('load', () => resolve(this._finishImage()));
        img.addEventListener('error', reject);
      });
    }
  }

  _finishImage() {
    if (window.createImageBitmap) {
      return window.createImageBitmap(this._img, { premultiplyAlpha: "none" }).then((imgBitmap) => {
        this._imgBitmap = imgBitmap;
        return Promise.resolve(this);
      });
    }
    return Promise.resolve(this);
  }

  get format() {
    return 6408;//GL.RGBA;
  }

  get width() {
    return this._img.width;
  }

  get height() {
    return this._img.height;
  }

  waitForComplete() {
    return this._promise;
  }

  get textureKey() {
    return this._img.src;
  }

  get source() {
    return this._imgBitmap || this._img;
  }
}

export class UrlTexture extends ImageTexture {
  constructor(url) {
    let img = document.createElement("img");
    super(img);
    img.src = url;
  }
}

export class CanvasTexture extends Texture {
  constructor(canvas) {
    super();

    this._canvas = canvas;

    this._key = `DATA_${nextDataTextureIndex}`;
    nextDataTextureIndex++;
  }

  waitForComplete() {
    return Promise.resolve(this);
  }

  get format() {
    return 6408;//GL.RGBA;
  }

  get width() {
    return this._canvas.width;
  }

  get height() {
    return this._canvas.height;
  }

  get textureKey() {
    return this._key;
  }

  get source() {
    return this._canvas;
  }
}